package com.ykt.common.pay.wx;

import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class WxAppPayUtil {
	
	private final  static Logger log = LoggerFactory.getLogger(WxAppPayUtil.class);
	
	private static Prop prop = PropKit.use("wx.properties");
    private static String appid = prop.get("wx.appid");
    private static String mch_id = prop.get("wx.mch_id");
    private static String appsecret = prop.get("wx.appsecret");
    private static String partnerkey = prop.get("wx.partnerkey");
    private static String trade_type = prop.get("wx.trade_type");
	
	public static Map<String, Map<String, String>> getSignParam(WxPayVo tpWxPayDto){
		
//		String appid = "wx4f68321d8da53232";//微信开放平台创建应用后生成的
//		String mch_id = "1267667301";//受理商ID，身份标识 // 商户号
//		String appsecret = "8360de86bb3d4de07cf094aefdfd7910";//微信开放平台创建应用后生成的
//		String partnerkey = "b0a42ad2a1e850919e053ad5dfc7ee02";//apikey在商户后台配置的一个32位的key,微信商户平台-账户设置-安全设置-api安全
//		String trade_type = "APP";//JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付、WAP--手机浏览器H5支付
		
		String orderId = tpWxPayDto.getOrderId();// 订单号
		String out_trade_no = orderId;// 商户订单号
		
		String body = tpWxPayDto.getBody();// 商品描述根据情况修改
		
		String totalFee = getMoney(tpWxPayDto.getTotalFee());// 总金额以分为单位，不带小数点
		// 订单生成的机器 IP
		String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
		
		// 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
		String notify_url = tpWxPayDto.getNotifyUrl();
		
		String nonce_str = getNonceStr();// 随机字符串
		
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appid);
		packageParams.put("mch_id", mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);
		//packageParams.put("attach", attach);//附加数据，在查询API和支付通知中原样返回
		packageParams.put("out_trade_no", out_trade_no);
		packageParams.put("total_fee", totalFee);
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);
		packageParams.put("trade_type", trade_type);
		
		RequestHandler reqHandler = new RequestHandler(null, null);
		reqHandler.init(appid, appsecret, partnerkey);
		
		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" 
					+ "<appid>" + appid + "</appid>" 
					+ "<mch_id>" + mch_id + "</mch_id>" 
					+ "<nonce_str>" + nonce_str + "</nonce_str>" 
					+ "<sign>" + sign + "</sign>"
					+ "<body><![CDATA[" + body + "]]></body>" 
					+ "<out_trade_no>" + out_trade_no + "</out_trade_no>" 
					//+ "<attach>" + attach + "</attach>"
					+ "<total_fee>" + totalFee + "</total_fee>"
					+ "<spbill_create_ip>" + spbill_create_ip+ "</spbill_create_ip>" 
					+ "<notify_url>" + notify_url + "</notify_url>" 
					+ "<trade_type>" + trade_type + "</trade_type>"
					+ "</xml>";
		log.info("xml==="+xml);

		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		
		Map<String, Map<String, String>> result = new HashMap<>();
		String prepay_id = "";
		String appSign = "";
//		Map<String, String> wxReturnMap = new HashMap<String, String>();
		try{
			prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
//			wxReturnMap = new GetWxOrderno().getPayNoSign(createOrderURL, xml);
			
//			prepay_id = wxReturnMap.get("prepay_id");
//			appSign =  wxReturnMap.get("sign");
			
			log.info("prepay_id==="+prepay_id);
			
			Map<String, String> signParam = new HashMap<>();
			String timestamp = Sha1Util.getTimeStamp();
			signParam.put("appid", appid);  
			signParam.put("noncestr", nonce_str);  
			signParam.put("package", "Sign=WXPay");  
			signParam.put("partnerid", mch_id);  
			signParam.put("prepayid", prepay_id);  
			signParam.put("timestamp", timestamp); 
			
			
			SortedMap<String, String> newSignParam = new TreeMap<String, String>();
			newSignParam.put("appid", appid);
			newSignParam.put("noncestr", nonce_str);
			newSignParam.put("package", "Sign=WXPay"); 
			newSignParam.put("partnerid", mch_id);  
			newSignParam.put("prepayid", prepay_id);  
			newSignParam.put("timestamp", timestamp); 
			//appid=wx7aed7efd3bbde5ef&noncestr=1609041071&package=Sign=WXPay&partnerid=1326524701&prepayid=wx2016033116074281a1440b8d0603160283&timestamp=1459411745&key=R54Gfd78w13sTGjkpSec7802XCOPEsvg
			//appid=wx7aed7efd3bbde5ef&noncestr=1630328999&package=Sign=WXPay&partnerid=1326524701&prepayid=wx201603311629102e5ee094b40867812504&timestamp=1459413033&key=R54Gfd78w13sTGjkpSec7802XCOPEsvg

			String newSign = reqHandler.createAppSign(newSignParam);
			
			signParam.put("sign", newSign);
			
			result.put("signParam", signParam);
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		return result;
	}

	
	/**
	 * 获取随机字符串
	 * @return
	 */
	public static String getNonceStr() {
		// 随机数
		String currTime = TenpayUtil.getCurrTime();
		// 8位日期
		String strTime = currTime.substring(8, currTime.length());
		// 四位随机数
		String strRandom = TenpayUtil.buildRandom(4) + "";
		// 10位序列号,可以自行调整。
		return strTime + strRandom;
	}

	/**
	 * 元转换成分
	 * @param amount
	 * @return
	 */
	public static String getMoney(String amount) {
		if(amount==null){
			return "";
		}
		// 金额转化为分为单位
		String currency =  amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额  
        int index = currency.indexOf(".");  
        int length = currency.length();  
        Long amLong = 0l;  
        if(index == -1){  
            amLong = Long.valueOf(currency+"00");  
        }else if(length - index >= 3){  
            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));  
        }else if(length - index == 2){  
            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);  
        }else{  
            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");  
        }  
        return amLong.toString(); 
	}

    public static boolean isPayServerCallBack(HttpServletRequest req){
        // 这种判断不是很严谨，存在攻击风险，但能解决问题
        return req.getRequestURI().contains("/weixin");
    }
}
